package com.gitee.wsl.unit.speed

import com.gitee.wsl.unit.BaseUnit
import com.gitee.wsl.unit.UnitType

sealed interface SpeedUnitType: UnitType<Double> {
    //千米/小时
    data object KMH: SpeedUnitType {
        override val baseUnit: Double = 1.0
    }

    //米/秒
    data object MS: SpeedUnitType {
        override val baseUnit: Double = KMH.baseUnit *3.6
    }

    //马赫
    data object E: SpeedUnitType {
        override val baseUnit: Double = KMH.baseUnit *1225
    }

    //节
    data object KN: SpeedUnitType {
        override val baseUnit: Double = KMH.baseUnit *1.852
    }

    //码
    data object M: SpeedUnitType {
        override val baseUnit: Double = KMH.baseUnit
    }

   //英里/小时
   data object MPH: SpeedUnitType {
       override val baseUnit: Double = KMH.baseUnit *1.609344
   }

    //光速
    data object C: SpeedUnitType {
        override val baseUnit: Double = KMH.baseUnit * 1.0792529E9
   }

}

sealed class SpeedUnit( value:Double, type: SpeedUnitType):
    BaseUnit<Double, SpeedUnitType>(value, type) {
    override fun toBase(): Double {
        return value*type.baseUnit
    }

    class KMH(value:Double):SpeedUnit(value,SpeedUnitType.KMH){
        override fun format(): String {
            return "$value/kmh"
        }
    }

    class MPH(value:Double):SpeedUnit(value,SpeedUnitType.MPH){
        override fun format(): String {
            return "$value/mph"
        }
    }

    class MS(value:Double):SpeedUnit(value,SpeedUnitType.MS){
        override fun format(): String {
            return "$value/ms"
        }
    }
    
    class E(value:Double):SpeedUnit(value,SpeedUnitType.E){
        override fun format(): String {
            return "$value/e"
        }
    }

    class KN(value:Double):SpeedUnit(value,SpeedUnitType.KN){
        override fun format(): String {
            return "$value/kn"
        }
    }

    class M(value:Double):SpeedUnit(value,SpeedUnitType.M){
        override fun format(): String {
            return "$value/m"
        }
    }

    class C(value:Double):SpeedUnit(value,SpeedUnitType.C){
        override fun format(): String {
            return "$value/c"
        }
    }

    override fun convertTo(desType: SpeedUnitType): SpeedUnit {
        return when(desType){
             SpeedUnitType.KMH -> KMH(toBase()/desType.baseUnit)
             SpeedUnitType.MS -> MS(toBase()/desType.baseUnit)
             SpeedUnitType.E -> E(toBase()/desType.baseUnit)
             SpeedUnitType.KN -> KN(toBase()/desType.baseUnit)
             SpeedUnitType.M -> M(toBase()/desType.baseUnit)
             SpeedUnitType.C -> C(toBase()/desType.baseUnit)
             SpeedUnitType.MPH -> MPH(toBase()/desType.baseUnit)
        }
    }
 }

val Number.kmh get() = SpeedUnit.KMH(toDouble())

val Number.mph get() = SpeedUnit.MPH(toDouble())

